from flask import Flask
from flask import request
from milvus_support import MilvusBase as milvus_support
from sentence_transformers import SentenceTransformer
import json, requests
import os

app = Flask(__name__)


@app.route('/support', methods=["POST"])
def index():
    data = request.get_data()
    json_data = json.loads(data)
    question = json_data['question']
    #history = json_data['history']

    ''' 召回器 '''
    # top_k参数
    top_k = 3
    # 将用户输入的问题embedding
    embeddings_1 = model.encode(question, normalize_embeddings=True)
    # 召回
    query_list, answer_list, score_list, text_list, dis_list = qa_text_retriever(embeddings_1, top_k)

    ''' 背景知识拼接+响应 '''
    # 得分统计
    qa_max_score = float(max(score_list))
    qa_text_max_score = float(max(score_list + dis_list))
    max_score = 0.9
    min_score = 0.5

    if qa_max_score > max_score:
        result = ("对话要求：\n"
                    "1. 你是超聚变数字技术有限公司产品的智能客服，当前客户向你提出问题已经有标准答案，你只需要将下面正确回答中的内容一摸一样的复述即可。\n"
                    "2. 正确回答中的链接无需访问，只需要一摸一样的将链接输出给客户即可。\n"
                    "3. 正确答案可能让客户参考一个链接，你只需要复述正确答案给客户。 \n"
                    )
        result += "正确回答: \n"
        result += answer_list[0]
    elif qa_text_max_score < min_score:
        result = "作为超聚变数字技术有限公司产品的智能客服，你必须保证你的回答专业、严谨。你只能回答超聚变产品相关的问题。\n结合上文背景知识，回答问题。\n"
    else:
        result = prompt_response(min_score, query_list, answer_list,
                                 score_list, text_list, dis_list, top_k, question)

    # 生成响应
    msg = {"code": 200, "message": "success", "result": result}
    return msg


def chat_qwen_72B(prompt):
    headers = {
        "Content-Type": "application/json",
        "Authorization": "Bearer sk-ChtJNYJD1sm5FqwA7bE8EfFa3eE847Fa9758E5626d64Cc9a"
    }
    data = {
        "model": "Qwen-72B-Chat",
        "messages": [{"role": "user", "content": prompt}]
    }

    response = requests.post("http://70.182.56.14:11000/v1/chat/completions", data=json.dumps(data),
                             headers=headers).content
    return str(response, encoding='utf-8')


def init_model():
    global model, milvus_cli
    model = SentenceTransformer('/model/data/transformers/BAAI/bge-large-zh-v1.5')
    config = {"milvus_host": "70.182.56.3", "milvus_port": 19530, "VECTOR_DIM": 1024, "METRIC_TYPE": "COSINE"}
    milvus_cli = milvus_support(**config)


def qa_text_retriever(embeddings, top_k):
    # QA问答召回的问题、答案、分数
    query_list, answer_list, score_list = milvus_cli.search_question('support_qa', [embeddings], top_k)

    # 文本召回的文本块、分数
    text_list, dis_list = milvus_cli.search_text('support_text', [embeddings], top_k)

    # 后台打印
    print("-------------")
    print("QA召回的问题：", query_list)
    print("**********")
    print("QA召回的答案：", answer_list)
    print("**********")
    print("QA召回的得分：", score_list)
    print("**********")
    print("文本召回的文本块：", text_list)
    print("**********")
    print("文本召回的得分：", dis_list)
    print("-------------")

    return query_list, answer_list, score_list, text_list, dis_list


def prompt_response(min_score, query_list, answer_list,
                    score_list, text_list, dis_list, top_k, question):
    # 拼接背景知识
    message = "你的背景知识: \n"
    for i in range(top_k):
        if score_list[i] >= min_score:
            message += query_list[i]
            message += "\n"
            message += answer_list[i]
            message += "\n"
        else:
            break

    for i in range(top_k):
        if dis_list[i] >= min_score:
            message += text_list[i]
            message += "\n"

    message += ("对话要求：\n"
                "1. 背景知识是最新的超聚变数字技术有限公司的产品信息，使用背景知识回答问题。\n"
                "2. 优先使用背景知识的内容回答我的问题，答案应与背景知识严格一致。\n"
                "3. 背景知识无法回答我的问题时，可以忽略背景知识，根据你的知识来自由回答。\n"
                "4. 作为超聚变数字技术有限公司的产品客服，使用对话的风格，自然的回答问题。\n"
                "5. 尽可能向客户提供背景知识中的给出的网址、链接。\n"
                "6. 你只能回答超聚变产品相关的问题，超聚变和华为没有任何关系。 \n"
                "我的问题是:\n")
    message += question

    # 返回结果
    return message


if __name__ == '__main__':
    init_model()
    app.run(host='70.182.42.131',
            port=8283)
